package com.powernode.impl;

import cn.hutool.core.util.StrUtil;
import com.powernode.constant.AuthConstants;
import com.powernode.factory.LoginStrategyFactory;
import com.powernode.strategy.LoginStrategy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * 项目自己的认证流程
 */
/*
    UserDetailsService接口里默认·是InMemoryUser这个类
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private LoginStrategyFactory loginStrategyFactory;

    /**
     *
     * @param username the username identifying the user whose data is required.
     * @return 返回security框架认识的一个对象类型。
     * @throws UsernameNotFoundException 用户名未找到异常
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //1.获取请求对象
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = null;
        if (requestAttributes != null) {
            request = requestAttributes.getRequest();
        }

        //2.从请求头中获取登录类型
        String loginType = null;
        if (request != null) {
            loginType = request.getHeader(AuthConstants.LOGIN_TYPE);
        }

        //判断请求来自与哪个系统 但是如果以后再来新角色新权限，或者手机号登录等，可扩展性差，用工厂/策略接口
        /*if (AuthConstants.SYS_USER_LOGIN.equals(loginType)){

        }else {

        }*/

        //3.1.判断 如果请求头中没有类型
        if(StrUtil.isBlank(loginType)){
            throw new InternalAuthenticationServiceException("请求头中没有类型，非法登录，登录类型不匹配");
        }

        //3.2.有值，通过登录工厂获取具体的·登录策略对象
        LoginStrategy instance = loginStrategyFactory.getInstance(loginType);

        return instance.realLogin(username);
    }
}
